<html><head><meta charset="utf-8"/><title>标准对象</title></head><body><h1>标准对象</h1><div class="x-wiki-content x-main-content">
 <p>
  在JavaScript的世界里，一切都是对象。
 </p>
 <p>
  但是某些对象还是和其他对象不太一样。为了区分对象的类型，我们用
  <code>
   typeof
  </code>
  操作符获取对象的类型，它总是返回一个字符串：
 </p>
 <pre><code>typeof 123; // 'number'
typeof NaN; // 'number'
typeof 'str'; // 'string'
typeof true; // 'boolean'
typeof undefined; // 'undefined'
typeof Math.abs; // 'function'
typeof null; // 'object'
typeof []; // 'object'
typeof {}; // 'object'
</code></pre>
 <p>
  可见，
  <code>
   number
  </code>
  、
  <code>
   string
  </code>
  、
  <code>
   boolean
  </code>
  、
  <code>
   function
  </code>
  和
  <code>
   undefined
  </code>
  有别于其他类型。特别注意
  <code>
   null
  </code>
  的类型是
  <code>
   object
  </code>
  ，
  <code>
   Array
  </code>
  的类型也是
  <code>
   object
  </code>
  ，如果我们用
  <code>
   typeof
  </code>
  将无法区分出
  <code>
   null
  </code>
  、
  <code>
   Array
  </code>
  和通常意义上的object——
  <code>
   {}
  </code>
  。
 </p>
 <h3>
  包装对象
 </h3>
 <p>
  除了这些类型外，JavaScript还提供了包装对象，熟悉Java的小伙伴肯定很清楚
  <code>
   int
  </code>
  和
  <code>
   Integer
  </code>
  这种暧昧关系。
 </p>
 <p>
  <code>
   number
  </code>
  、
  <code>
   boolean
  </code>
  和
  <code>
   string
  </code>
  都有包装对象。没错，在JavaScript中，字符串也区分
  <code>
   string
  </code>
  类型和它的包装类型。包装对象用
  <code>
   new
  </code>
  创建：
 </p>
 <pre><code>var n = new Number(123); // 123,生成了新的包装类型
var b = new Boolean(true); // true,生成了新的包装类型
var s = new String('str'); // 'str',生成了新的包装类型
</code></pre>
 <p>
  虽然包装对象看上去和原来的值一模一样，显示出来也是一模一样，但他们的类型已经变为
  <code>
   object
  </code>
  了！所以，包装对象和原始值用
  <code>
   ===
  </code>
  比较会返回
  <code>
   false
  </code>
  ：
 </p>
 <pre><code>typeof new Number(123); // 'object'
new Number(123) === 123; // false

typeof new Boolean(true); // 'object'
new Boolean(true) === true; // false

typeof new String('str'); // 'object'
new String('str') === 'str'; // false
</code></pre>
 <p>
  所以
  <em>
   闲的蛋疼也不要使用包装对象
  </em>
  ！尤其是针对
  <code>
   string
  </code>
  类型！！！
 </p>
 <p>
  如果我们在使用
  <code>
   Number
  </code>
  、
  <code>
   Boolean
  </code>
  和
  <code>
   String
  </code>
  时，没有写
  <code>
   new
  </code>
  会发生什么情况？
 </p>
 <p>
  此时，
  <code>
   Number()
  </code>
  、
  <code>
   Boolean
  </code>
  和
  <code>
   String()
  </code>
  被当做普通函数，把任何类型的数据转换为
  <code>
   number
  </code>
  、
  <code>
   boolean
  </code>
  和
  <code>
   string
  </code>
  类型（注意不是其包装类型）：
 </p>
 <pre><code>var n = Number('123'); // 123，相当于parseInt()或parseFloat()
typeof n; // 'number'

var b = Boolean('true'); // true
typeof b; // 'boolean'

var b2 = Boolean('false'); // true! 'false'字符串转换结果为true！因为它是非空字符串！
var b3 = Boolean(''); // false

var s = String(123.45); // '123.45'
typeof s; // 'string'
</code></pre>
 <p>
  是不是感觉头大了？这就是JavaScript特有的催眠魅力！
 </p>
 <p>
  总结一下，有这么几条规则需要遵守：
 </p>
 <ul>
  <li>
   <p>
    不要使用
    <code>
     new Number()
    </code>
    、
    <code>
     new Boolean()
    </code>
    、
    <code>
     new String()
    </code>
    创建包装对象；
   </p>
  </li>
  <li>
   <p>
    用
    <code>
     parseInt()
    </code>
    或
    <code>
     parseFloat()
    </code>
    来转换任意类型到
    <code>
     number
    </code>
    ；
   </p>
  </li>
  <li>
   <p>
    用
    <code>
     String()
    </code>
    来转换任意类型到
    <code>
     string
    </code>
    ，或者直接调用某个对象的
    <code>
     toString()
    </code>
    方法；
   </p>
  </li>
  <li>
   <p>
    通常不必把任意类型转换为
    <code>
     boolean
    </code>
    再判断，因为可以直接写
    <code>
     if (myVar) {...}
    </code>
    ；
   </p>
  </li>
  <li>
   <p>
    <code>
     typeof
    </code>
    操作符可以判断出
    <code>
     number
    </code>
    、
    <code>
     boolean
    </code>
    、
    <code>
     string
    </code>
    、
    <code>
     function
    </code>
    和
    <code>
     undefined
    </code>
    ；
   </p>
  </li>
  <li>
   <p>
    判断
    <code>
     Array
    </code>
    要使用
    <code>
     Array.isArray(arr)
    </code>
    ；
   </p>
  </li>
  <li>
   <p>
    判断
    <code>
     null
    </code>
    请使用
    <code>
     myVar === null
    </code>
    ；
   </p>
  </li>
  <li>
   <p>
    判断某个全局变量是否存在用
    <code>
     typeof window.myVar === 'undefined'
    </code>
    ；
   </p>
  </li>
  <li>
   <p>
    函数内部判断某个变量是否存在用
    <code>
     typeof myVar === 'undefined'
    </code>
    。
   </p>
  </li>
 </ul>
 <p>
  最后有细心的同学指出，任何对象都有
  <code>
   toString()
  </code>
  方法吗？
  <code>
   null
  </code>
  和
  <code>
   undefined
  </code>
  就没有！确实如此，这两个特殊值要除外，虽然
  <code>
   null
  </code>
  还伪装成了
  <code>
   object
  </code>
  类型。
 </p>
 <p>
  更细心的同学指出，
  <code>
   number
  </code>
  对象调用
  <code>
   toString()
  </code>
  报SyntaxError：
 </p>
 <pre><code>123.toString(); // SyntaxError
</code></pre>
 <p>
  遇到这种情况，要特殊处理一下：
 </p>
 <pre><code>123..toString(); // '123', 注意是两个点！
(123).toString(); // '123'
</code></pre>
 <p>
  不要问为什么，这就是JavaScript代码的乐趣！
 </p>
</div>
</body></html>